<?php
/**
 * Created by PhpStorm.
 * User: Korbin
 * Date: 2018/11/10
 * Time: 11:17
 */

namespace app\script\command;

use app\common\model\Job;
use app\common\model\News;
use app\common\model\NewsContent;
use app\common\model\NewsType;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;

class Kami extends Base
{

    private $listKey = 'posts';//获取数据区域
    private $startUrl = 'https://app.kami.com.ph/v3/post/list?';
    private $classNameArr=['LATEST','MGA BALITA NGAYON SA PILPINAS','POLITICAL NEWS','ENTERTANMENT','WORLD NEWS','BUSSINESS AND ECONOMY','SPORTS','EDUCATION AND TECHNOLOGY','OPINION','LIFE AND STYLE','PHOTOS','SPIRITUALITY'];
    private $baseArr=[
        'screenWidth=1080&category=latest&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=local&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=politics&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=entertainment&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=foreign&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=business&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=sports&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=education&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=opinion&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=life-style-2&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=photos&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId=',
        'screenWidth=1080&category=spirituality&short=0&per-page=15&screenHeight=1920&showTrending=1&offsetPostId='
    ];
    private $offsetPostId=[0,0,0,0,0,0,0,0,0,0,0,0];
    /**
     * 设置执行名称及配置传入参数、脚本描述
     */
    protected function configure()
    {
        //设置执行名称
        $this->setName('kamiNews')
            ->addOption('job', 'j', Option::VALUE_OPTIONAL)
            ->setDescription('Run all the time');
    }

    /*********************公用验证部分************************************/
    /*
     * 执行脚本任务
     *
     * @param Input $input
     * @param Output $output
     */
    protected function execute(Input $input, Output $output)
    {
        $job = $input->getOption('job');
        if (empty($job)) {
            $output->writeln('请传入执行任务ID：' . date('Y-m-d H:i:s'));
            exit();
        }

        $output->writeln('脚本开始：' . date('Y-m-d H:i:s'));
        $jobModel = new Job();
        $jobInfo = $jobModel->where(['id' => $job])->find();//获取任务配置信息
        if (empty($jobInfo)) {
            $output->writeln('任务ID不存在：' . date('Y-m-d H:i:s'));
            exit();
        } else {
            $jobInfo = $jobInfo->toArray();
        }
        //$this->redis->hSet('job_status',$job,1);
        $jobRedisInfo = $this->redis->hGet('jobHash', $job);//获取任务redis记录
        if (empty($jobRedisInfo)) {
            $jobRedisData = [
                'planned_quantity' => $jobInfo['planned_quantity'],
                'real_quantity' => (empty($jobInfo['real_quantity']) ? 0 : $jobInfo['real_quantity']),
                'shortvideo_num' => (empty($jobInfo['shortvideo_num']) ? 0 : $jobInfo['shortvideo_num']),
                'smallvideo_num' => (empty($jobInfo['smallvideo_num']) ? 0 : $jobInfo['smallvideo_num']),
                'finsh_time' => '',
            ];
        } else {
            $jobRedisData = json_decode($jobRedisInfo, true);
            $jobRedisData['planned_quantity'] = $jobInfo['planned_quantity'];
        }
        $newsTypeId = [];
        $this->createType($jobInfo,$newsTypeId);
        //开始循环执行采集任务
        while (true) {
            //采集开始执行验证采集开关是否打开
            $jobStatus = $this->redis->hGet('job_status', $job);
            if ($jobStatus != 1) {
                break;//采集开关关闭时跳出循环结束脚本执行
            }

            foreach ($this->classNameArr as $key=>$val) {
                $url=$this->startUrl.$this->baseArr[$key].$this->offsetPostId[$key];

                $result = $this->getApiData($url);//获取采集源结果

                //验证是否有相应的采集数据
                if(!is_array($result)){
                    continue;
                }
                if (is_array($result) && array_key_exists($this->listKey, $result)) {
                    $lists = $result[$this->listKey];
                } else {
                    $output->writeln($this->getName() . '采集源服务器出错或找不到采集信息！'. date('Y-m-d H:i:s'));
                    continue;
                }

                //开始拼装数据
                $insertData = [];
                if (!empty($lists)) {
                    $id=$this->createData($lists, $jobInfo, $jobRedisData, $insertData,$newsTypeId[$val],$key);//对源数据进行对应入库
                    $this->offsetPostId[$key]=$id;
                    if (!empty($insertData)) {
                        //当实际采集数据大于等于计划采集数据量时设置redis开关值
                        if (($jobRedisData['planned_quantity'] - $jobRedisData['real_quantity']) <= 0) {
                            $this->redis->hSet('job_status', $job, 2);//正常完成值为2
                            $jobRedisData['finsh_time'] = date('Y-m-d H:i:s');//正常完成时间记录
                            $jobModel->save(['job_status'=>2,'status_time'=>date('Y-m-d H:i:s')],['id'=>$job]);
                        }
                        $this->redis->hSet('jobHash', $job, json_encode($jobRedisData));
                        $output->writeln('【' . $this->getName() . '采集成功】本次采集入库数据条数为【' . count($insertData) . '】'. date('Y-m-d H:i:s'));
                    } else {
                        $output->writeln('【' . $this->getName() . '执行成功】本次采集无符合要求的数据入库!'. date('Y-m-d H:i:s'));
                    }
                } else {
                    $output->writeln('【'.$this->getName().'请求成功】本次请求无返回正确数据!'.date('Y-m-d H:i:s'));
                    continue;
                }
            }

            //间隔随机时间
            $sleep = rand(5, 10);
            sleep($sleep);
        }

        $output->writeln($this->getName().'任务执行完毕：' . date('Y-m-d H:i:s'));
    }
    /*********************公用验证部分************************************/

    /**
     * 组装url进行数据获取
     * @param $url
     * @return mixed
     */
    private function getApiData($url)
    {
        $result = curl_get_https($url);

        $result = json_decode($result, true);
        return $result;
    }

    /**
     * 采集数据拼装入库
     *
     * @param $lists
     * @param $jobInfo
     * @param $jobRedisData
     * @param $insertData
     * @param $typeId
     * @param $k
     */
    private function createData($lists, $jobInfo, &$jobRedisData, &$insertData,$typeId,$k)
    {
        $news =  new News();
        $newContent=new NewsContent();

        $contentInsertData=[];
        $updateData = [];
        $id=0;
        $ids = [];
        foreach ($lists as $val) {
            if(!is_array($val)){
                continue;
            }

            $id=$val['id'];
            $data = [];
            //视频评论、点赞、收藏、分享数

            $data['thumb_num'] = array_key_exists('like_count',$val)?$val['like_count']:0;
            $data['comment_num'] = $val['commentsCount'];
            $data['watch_num'] = $val['views'];
            $data['share_num'] = 0;

            //验证视频是否符合采集需求
            $validateRes = $this->validateNum($data,$jobInfo);
            if ($validateRes == false) {
                continue;
            }
            //平台信息【可不动】
            $data['job_id'] = $jobInfo['id'];
            $data['language'] = $jobInfo['lang'];
            $data['country'] = $jobInfo['country'];
            $data['platform'] = $jobInfo['platform'];
            $data['create_by'] = $jobInfo['create_by'];
            $data['create_date'] = date('Y-m-d H:i:s');
            $data['update_by'] = $jobInfo['update_by'];
            $data['update_date'] = date('Y-m-d H:i:s');
            $data['remarks'] = '';

            //新闻信息
            $data['uni'] = $val['id'];//第三方视频唯一ID


            $data['title'] = $val['title'];//新闻标题
           /* $img = [];
            foreach($val['thumbnails'] as $arr){
                array_push($img,$arr['url']);
            }*/
            $data['cover_img'] = $val['imgSmall'];//封面
            $data['cover_show_type'] = 2;//封面类型
            $data['source']=$val['url'];
            $data['author_avatar'] = '';//作者头像
            $data['author_name'] = $val['author'];//作者姓名
            $data['create_time'] = strtotime($val['publishDate']);//创建时间
            $data['update_time'] = strtotime($val['modifyDate']);//更新时间
            $data['href']=$val['url'];
            $data['visit_count'] = $val['commentsCount'];//访问数量
            $data['type_id'] = $typeId;//访问数量
            $data['like_count'] = 0;//点赞数量
            $data['comment_count'] = $val['commentsCount'];//留言个数
            $data['unlike_count'] = 0;//
            $data['unlike_enable'] =0;//是否允许不喜欢
            $data['can_comment'] = 1;//是否允许评论,默认为1允许',
            $data['share_count'] = 0;//分享个数
            $data['listorder'] = 0;//排序
            $data['status'] = 1;//状态:1显示,2不显示

            $dataContent = [];
            $dataContent['id'] = com_create_guid();//生成唯一UUID
            $content = $val['content'];
            $contentStr='<img src="'.$val['img'].'" />';
            foreach($content as $contentVal){
                $contentStr.="<p>".$contentVal['content']."</p>";
            }
            $dataContent['content']=$contentStr;
            $dataContent['update_time']=strtotime($val['modifyDate']);//更新时间
            $dataContent['create_by']=$data['create_by'];
            $dataContent['create_date']=date('Y-m-d H:i:s');
            $dataContent['update_by']=$data['update_by'];

            $dataContent['remarks']='';
            //判断是否 已经存在
            $isExist = $news->field('id')->where([
                'uni' => $data['uni']
            ])->find();
            if ($isExist) {
                //continue;
                $data['id'] =$isExist['id'];
                $updateData[] = $data;
            }else{
                $data['id'] = com_create_guid();//生成唯一UUID
                $jobRedisData['real_quantity'] += 1;//实际采集数量+1
                $dataContent['news_id']=$data['id'];
                $contentInsertData[]=$dataContent;
                $insertData[] = $data;
            }
            array_push($ids, $val['id']);
        }
        //71a86b74d5c2a90671b452c2f32eea98
        if(!empty($ids)){
            /*$minIdarr=[0,0,0,0,0,0,0,0,0,0,0,0];
            $redisIdarr= json_decode($this->redis->hGet($this->getName().'Hash', hash('md5',$this->getName())),true);
            foreach($minIdarr as $mk=>&$mv){
                if(isset($redisIdarr[$mk])){
                    $mv=$redisIdarr[$mk];
                }
            }
            $minIdarr[$k]= min($ids);
            $this->redis->hSet($this->getName().'Hash', hash('md5',$this->getName()),json_encode($minIdarr));*/
            $this->redis->hSet($this->getName().'Hash', hash('md5',$this->getName().$k),min($ids));
        }
        $lastNews=$news->where('uni',$id)->find();
        $news->allowField(true)->isUpdate(true)->saveAll($updateData);
        $news->allowField(true)->isUpdate(false)->saveAll($insertData,false);
        $newContent->allowField(true)->isUpdate(false)->saveAll($contentInsertData, false);
        $insertData = array_merge($insertData,$updateData);
        if($lastNews){
            /*$redisIdarr= json_decode($this->redis->hGet($this->getName().'Hash', hash('md5',$this->getName())),true);
            $id=$redisIdarr?$redisIdarr[$k]:0;*/
            $redisId=$this->redis->hGet($this->getName().'Hash', hash('md5',$this->getName().$k));
            if($redisId && $redisId<$id){
                $id=$redisId;
            }
        }
        return $id;
    }

    /**
     * 验证采集数据是否符合条件
     *
     * @param $data
     * @param $jobInfo
     * @return bool
     */
    private function validateNum($data,$jobInfo){
        $res = true;
        $keys = array_keys($data);
        foreach ($keys as $val){
            if($jobInfo[$val]>$data[$val]){
                $res = false;
                break;
            }
        }
        return $res;
    }

    /**
     * 创建平台类型
     *
     * @param $jobInfo
     * @param $newsTypeId
     */
    private function createType($jobInfo,&$newsTypeId){
        $newType=new NewsType();
        $newsTypeId = [];
        $newsTypeId = $newType->where(['platform'=>$jobInfo['platform']])->column('name,id');
        if(empty($newsTypeId)){
            $insertData=[];
            foreach($this->classNameArr as $val){
                $data['id']=com_create_guid();//生成唯一UUID
                $data['name']=$val;
                $data['platform']=$jobInfo['platform'];
                $data['type']=2;
                $data['status']=1;
                $data['create_time']=time();
                $data['sort']=0;
                $data['is_hot']=1;
                $data['create_by']=$jobInfo['create_by'];
                $data['create_date']=$jobInfo['create_date'];
                $data['update_by']=$jobInfo['update_by'];
                $data['update_date']=$jobInfo['update_date'];
                $insertData[]=$data;
                $newsTypeId[$data['name']] = $data['id'];
            }
            $newType->allowField(true)->insertAll($insertData);
        }
    }

}